/**
 * dlist.h
 * 双向循环链表类型及常见操作。*/
#ifndef DLIST_H
#define DLIST_H

/**
 * 根据结构体类型 type 中的名为 mn 成员的地址 ma 获取
 * type 结构体类型变量的首地址。*/
#define DL_START_ADDR(ma, type, mn) \
    ((type *) (((char *)(ma)) - (((type *)0)->mn)))

typedef struct dlNode DL_NODE_S;

struct dlNode
{
    struct dlNode *prev;
    struct dlNode *next;
};

inline static void 
dlInit(DL_NODE_S *head)
{
    head->next = head->prev = head;
    return ;
}

inline static void 
dlAddNext(DL_NODE_S *cur, DL_NODE_S *add)
{
    add->next = cur->next;
    add->prev = cur;
    cur->next->prev = add;
    cur->next = add;
    return ;
}

inline static void 
dlAddPrev(DL_NODE_S *cur, DL_NODE_S *add)
{
    add->next = cur;
    add->prev = cur->prev;
    cur->prev->next = add;
    cur->prev = add;
    return ;
}

inline static void 
dlDel(DL_NODE_S *del)
{
    del->next->prev = del->prev;
    del->prev->next = del->next;
    dlInit(del);
    return ;
}

inline static int 
dlIsEmpty(DL_NODE_S *head)
{
    return head->next == head;
}

inline static void 
dlMoveHead(DL_NODE_S *dst, DL_NODE_S *src)
{
    if (dlIsEmpty(src)) return ;
    dst->next->prev = src->prev;
    src->prev->next = dst->next;
    dst->next = src->next;
    src->next->prev = dst;
    dlInit(src);
}

inline static void 
dlMoveTail(DL_NODE_S *dst, DL_NODE_S *src)
{
    if (dlIsEmpty(src)) return ;
    dst->prev->next = src->next;
    src->next->prev = dst->prev;
    dst->prev = src->prev;
    src->prev->next = dst;
    dlInit(src);
}

#endif